/**
 * Copyright:Copyright(c)2014-2017
 * Company:厦门市易致达物联网科技有限公司
 *
 * @version 1.0
 */
package shop.controller.front.orderpay;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import shop.core.FrontBaseController;
import shop.core.RequestHolder;
import shop.core.Services;
import shop.core.common.bean.JSONResult;
import shop.core.common.bean.WxContainer;
import shop.core.common.oscache.SystemManager;
import shop.core.plugins.wxpay.*;
import shop.core.util.AddressUtils;
import shop.services.front.offlineAccount.bean.OfflineAccount;
import shop.services.front.account.AccountService;
import shop.services.front.account.bean.Account;
import shop.services.front.offlineAccount.OfflineAccountService;
import shop.services.front.order.OrderService;
import shop.services.front.order.bean.Order;
import shop.services.front.orderdetail.bean.Orderdetail;
import shop.services.front.orderdetail.impl.OrderdetailServiceImpl;
import shop.services.front.orderpay.OrderpayService;
import shop.services.front.orderpay.bean.Orderpay;
import shop.services.front.organize.OrganizeService;
import shop.services.front.organize.bean.Organize;
import shop.services.front.product.ProductService;
import shop.services.front.product.bean.Product;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.BufferedReader;
import java.math.BigDecimal;
import java.util.*;

/**
 * @类名称：OrderpayController
 * @创建人：Ltz
 * @创建时间：2017-07-04 下午22:17:02
 * @版本号：1.0
 * @描述：
 */
@Controller
@RequestMapping("/front/orderpay")
public class OrderpayController extends FrontBaseController<Orderpay> {
    private static final Logger logger = LoggerFactory.getLogger(OrderpayController.class);


    @Resource
    private OrderpayService orderpayService;
    @Resource
    private OrderService orderService;
    @Resource
    private OrderdetailServiceImpl orderdetailService;
    @Resource
    private ProductService productService;
    @Resource
    private AccountService accountService;
    @Resource
    private OfflineAccountService offlineAccountService;
    @Resource
    private OrganizeService organizeService;

    @Override
    public Services<Orderpay> getService() {
        return orderpayService;
    }

    private WXPay wxpay;
    private WXPayConfigImpl config;

    /**
     * 获取预支付信息
     *
     * @param session
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/getPrepayId", method = RequestMethod.GET)
    @ResponseBody
    public JSONResult getPrepayId(HttpSession session, Order order) throws Exception {
        jsonResult = new JSONResult();
        order.setStatus("init");
        String type = order.getType();
        String out_trade_no = UUID.randomUUID().toString().replace("-", "");
        String orderID = "";
        logger.debug("订单类型为：" + type);
//        为订单支付时插入订单
        if (type != null && type.equals("order")) {
            if (order.getId() != null && !order.getId().equals("")) {
                logger.debug("已有订单：");
                orderID = order.getId() + "Or";
                order = orderService.selectById(order.getId());
                logger.debug("商品ID为：" +order.getProductID());
            } else {
                logger.debug("插入订单：");
                orderID = String.valueOf(orderService.insert(order));
                orderID = orderID + "Or";
                logger.debug("商品ID为：" +order.getProductID());
            }
        } else {
            //募捐支付时更新募捐金额
            logger.debug("更新募捐活动信息：");
            OfflineAccount offlineAccount = offlineAccountService.selectById(order.getId());
            //增加募捐活动付款标识Of
            orderID = offlineAccount.getId() + "Of";
            offlineAccount.setStatus("O");
            offlineAccount.setContributions(order.getPtotal());
            offlineAccountService.update(offlineAccount);
        }
        config = WXPayConfigImpl.getInstance();
        wxpay = new WXPay(config);
        Float ftotal_fee = Float.parseFloat(order.getPtotal()) * 100;
        String total_fee = String.valueOf(ftotal_fee.intValue());//商品总价
        logger.debug("商品总价为：" + total_fee);
        logger.debug("订单号为：" + out_trade_no);
        HashMap<String, String> data = new HashMap<String, String>();
        data.put("body", "华贝生物科技");
        data.put("out_trade_no", out_trade_no);
        data.put("device_info", "");
        data.put("total_fee", total_fee);
        String clientIp = AddressUtils.getIp(RequestHolder.getRequest()).split(",")[0];
        data.put("spbill_create_ip", clientIp);
        data.put("notify_url", "http://www.kekelvxing.cn/front/orderpay/notify");
        data.put("trade_type", "JSAPI");
        data.put("product_id", UUID.randomUUID().toString().replace("-", ""));
        data.put("openid", session.getAttribute("userOpenId").toString());
        try {
            Map<String, String> r = wxpay.unifiedOrder(data);
            logger.debug("获得预支付信息为：" + r.get("return_msg") + ",获得返回状态码为：" + r.get("return_code"));
            //回传页面参数
            Map<String, String> reqData = new HashMap<String, String>();
            reqData.put("appId", config.getAppID());
            reqData.put("timeStamp", String.valueOf(new Date().getTime() / 1000));
            reqData.put("nonceStr", r.get("nonce_str"));
            reqData.put("signType", "MD5");
            reqData.put("package", "prepay_id=" + r.get("prepay_id"));
            String paySign = WXPayUtil.generateSignature(reqData, config.getKey(), WXPayConstants.SignType.MD5);
            reqData.put("paySign", paySign);
            logger.debug("回传页面参数填写完成");
//          在本地插入订单支付信息
            logger.debug("在本地插入订单支付信息");
            Orderpay orderpay = new Orderpay();
            orderpay.setOrderId(orderID);
//            获取支付记录表判断是否存在支付订单
            Orderpay anOrderpay = orderpayService.selectOne(orderpay);
            if (anOrderpay != null) {
                anOrderpay.setPrepayId(r.get("prepay_id"));
                anOrderpay.setOutTradeNo(out_trade_no);
                getService().update(anOrderpay);
                jsonResult.setData(reqData);
                jsonResult.setSuccess(true);
                return jsonResult;
            } else {
                orderpay.setPayStatus("0");
                orderpay.setPrepayId(r.get("prepay_id"));
                orderpay.setPayType(data.get("trade_type"));
                BigDecimal payAmount = new BigDecimal(order.getPtotal());
                orderpay.setPayAmount(payAmount);
                orderpay.setOutTradeNo(out_trade_no);
                orderpay.setProductBody(data.get("body"));
                getService().insert(orderpay);
//          model.addAttribute("e", reqData);
                jsonResult.setData(reqData);
                jsonResult.setSuccess(true);
                return jsonResult;
            }
        } catch (Exception e) {
            logger.debug("打印错误日志：");
            e.printStackTrace();
            jsonResult.setSuccess(false);
            return jsonResult;
        }
    }

    /**
     * 微信支付回调接口
     *
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "notify", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public String payNotifyUrl(HttpServletRequest request, HttpServletResponse response) throws Exception {
        BufferedReader reader = null;
        reader = request.getReader();
        String line = "";
        String xmlString = null;
        StringBuffer inputString = new StringBuffer();
        while ((line = reader.readLine()) != null) {
            inputString.append(line);
        }
        xmlString = inputString.toString();
        request.getReader().close();
        Map<String, String> reciveData = WXPayUtil.xmlToMap(xmlString);
        logger.debug("收到支付回调结果:" + reciveData);
        String out_trade_no = reciveData.get("out_trade_no");
        Orderpay orderpay=new Orderpay();
        orderpay.setOutTradeNo(out_trade_no);
        logger.debug("查询本地支付记录" );
        orderpay=getService().selectOne(orderpay);
        String orderID=orderpay.getOrderId();
        String rsType = reciveData.get("return_code");
        HashMap<String, String> data = new HashMap<String, String>();
        String reStr = "";
        if (rsType.equals("SUCCESS")) {
            if (orderID.contains("Or")) {
//                去除订单标识
                orderID = orderID.substring(0, orderID.length() - 2);
                Order order = orderService.selectById(orderID);
                if (order.getStatus().equals("pass") && order.getPaystatus().equals("y")) {
                    data.put("return_code", "SUCCESS");
                    data.put("return_msg", "OK");
                    reStr = WXPayUtil.mapToXml(data);
                    return reStr;
                } else {
//                获取订单详情，更新产品的销量
                    logger.debug("获取订单详情");
                    Orderdetail orderdetail = new Orderdetail();
                    orderdetail.setOrderID(Integer.parseInt(orderID));
                    List<Orderdetail> orderdetailList = orderdetailService.selectList(orderdetail);
                    for (Orderdetail anOrdedetail : orderdetailList) {
                        logger.debug("更新产品的销量");
                        Product product = new Product();
                        product.setId(anOrdedetail.getProductID());
                        Integer sellcout = productService.selectOne(product).getSellcount();
                        logger.debug("旧的产品销量：" + anOrdedetail.getNumber());
                        Integer newSellCout = Integer.parseInt(anOrdedetail.getNumber()) + sellcout;
                        logger.debug("新的产品销量：" + newSellCout);
                        product.setSellcount(newSellCout);
                        productService.update(product);
                    }
//                更新付款用户的消费总金额
                    logger.debug("更新付款用户的消费总金额");
                    Account account = new Account();
                    account.setId(order.getAccountID());
                    account = accountService.selectOne(account);
                    Float newScore = account.getScore() + Float.parseFloat(order.getPtotal());
                    account.setScore(newScore.intValue());
                    accountService.update(account);
//                更新订单状态
                    logger.debug("更新订单状态");
                    order.setPaystatus("y");
                    order.setStatus("pass");
                    order.setProductID(null);
                    orderService.update(order);
                }
            } else {
//                去除订单标识
                logger.debug("更新募捐活动状态");
                orderID = orderID.substring(0, orderID.length() - 2);
//                获取活动参与详情
                OfflineAccount offlineAccount = offlineAccountService.selectById(orderID);
                offlineAccount.setStatus("1");
                offlineAccountService.update(offlineAccount);
                logger.debug("更新机构金额");
                Organize organize=new Organize();
                organize.setId(offlineAccount.getOrganizeID());
                organize=organizeService.selectOne(organize);
                organize.setSum(offlineAccount.getContributions());
                organize.setUnCash(offlineAccount.getContributions());
                organizeService.update(organize);
            }
//                更新本地订单支付表信息
            logger.debug("更新本地订单支付表信息");
            orderpay.setTransactionId(reciveData.get("transaction_id"));
            orderpay.setPayStatus("1");
            getService().update(orderpay);
        }
        data.put("return_code", "SUCCESS");
        data.put("return_msg", "OK");
        reStr = WXPayUtil.mapToXml(data);
        return reStr;
    }

    /**
     * 微信扫一扫测试
     * @param model
     * @return
     */
    @RequestMapping("/toScan")
    public String wxScan(Model model) {
        String timeStamp=String.valueOf(new Date().getTime() / 1000);
        String nonceStr = UUID.randomUUID().toString().replace("-", "");
        try {
            Map<String, String> reqData = new HashMap<String, String>();
            reqData.put("jsapi_ticket", systemManager.getJsapiTicket());
            reqData.put("timestamp", timeStamp);
            reqData.put("noncestr", nonceStr);
            reqData.put("url", "http://www.kekelvxing.cn/front/orderpay/toScan");
            String signature = WXPayUtil.generateSignature(reqData, null, WXPayConstants.SignType.SHA1);
            model.addAttribute("appId", WxContainer.appid);
            model.addAttribute("timestamp", timeStamp);
            model.addAttribute("noncestr", nonceStr);
            model.addAttribute("signature", signature);
        }catch (Exception e){
            logger.error("获取微信jsapi参数失败");
        }

        return "/front/order/wxScan";
    }
}
